2

打算把最近一年学的Linux做个整理,就从文件权限开始吧

  1. ugo基本权限
  2. acl权限
  3. suid,sgid,sticky高级权限
  4. selinux

ugo基本权限

一个文件对应三种权限对象,分别文件的所有者user、所属组group和其他人other
每个权限对象对应三种权限,分别是读r、写w和执行x
权限数字对应关系

权限名称 十进制 二进制
r 4 0100
w 2 0010
x 1 0001

这么设计的目的是rwx任意组合不会互相影响
相关操作举例

$ touch file1
$ ls -l file1
-rw-r--r-- 1 root root 0 Jul 14 15:15 file1  
$ mkdir dir1
drwxr-xr-x 1 root root 4096 Jul 14 15:15 dir1  

默认的文件权限为0644
默认的目录权限为0755
之所以默认权限为这些,是因为umask的值

$ umask
0022

umask默认值为0022,则目录默认权限为0777-0022=0755
而默认的文件权限在此基础上减去执行权限变为0644
至于0644、0755前面的0是什么,我们在高级权限中再介绍
umask命令只能临时生效,推出再登录后就又还原成默认的了,如果想要永远生效,可以更改/etc/profile或~/.bash_profile(没有则添加,有则修改)
而r、w、x三种权限对于目录和文件所表示的意义也不同,如下表

权限名称 文件 目录
r 可查看文件内容,如cat file1 可列出目录内容,如ls dir1
w 可更改文件内容,如echo 1 >> file1 可创建或删除目录中的文件(对于无x权限的目录,w权限无效)
x 可作为命令被执行 可进入目录,如cd dir1;可访问目录中的文件(当然也要看文件的权限)
权限更改

格式1 chmod {权限对象}{赋值符号}{权限} {文件名}
其中{权限对象}可以是u、g、o、a中的一种,分别代表所有者user、所属组group、其他人other、所有人all
格式2 chmod {权限数字} {文件名}

$ chmod u+x file1
$ chmod g+w,o-r,u=wrx file1
$ chmod 755 file1

小思考:

  1. 对于/root目录中一个其他人有读取权限的文件,新建一个用户,能否查看该文件?
  2. 修改根目录权限为777,新建一个用户,能否删除/etc目录?

acl权限

上面的文件file1,root用户有rw权限,root组用户和其他人有r权限,此时,我想让tom用户拥有x权限,怎么办?单凭ugo基本权限,貌似不能实现这种操作,这就要用到我们现在要说的acl权限了
acl权限是对ugo基本权限的扩展,用来实现对文件权限更精细的操控

  • 查看acl权限
$ getfacl file1 
# file: file1
# owner: root
# group: root
user::rw-
group::r--
other::r--

此时没有acl权限

  • 添加acl权限
$ setfacl -m u:tom:x file1
$ ls -l file1
-rw-r-xr--+ 1 root root 0 Oct 12 23:10 file1
$ getfacl file1 
# file: file1
# owner: root
# group: root
user::rw-
user:tom:--x
group::r--
mask::r-x
other::r--

添加完acl权限后发现,ls -l 的结果有了变化:
其中所属组的权限变成了rx,而原来是r,权限 -rw-r-xr-- 后面多了个 +
先说 +,表示该文件有acl扩展权限
此时 getfacl 查看acl权限发现,较最初无acl权限时多了两行

user:tom:--x
mask::r-x

此时 ls -l 所展示的所属组处的r-x其实不是所属组的权限,而是mask权限,而什么又是mask权限呢?
mask权限会随着新设置的acl的权限的变化而变化,它是该文件所有acl权限和group权限的并集,即此时mask的权限为 user:tom:--xgroup::r-- 权限的并集 r-x; 如果再添加一条acl权限,使tony组的用户有写入权限 setfacl -m g:jack:w,则此时mask的权限为 rwx
mask权限的作用是为了临时限制acl权限,举例说明,此时file1的详细权限为

user::rw-

user:tom:--x
group::r--
mask::r-x
other::r--

假设此时不只有tom有acl权限,jack、andy等人也有好多acl权限,此时要临时降低他们的权限,如何操作?难道用 setfacl -b file1 命令删除所有acl权限,如果用户多的话,删完再一个个地添加,这得多么麻烦呀!此时只需要临时禁止mask权限便可

$ setfacl -m m::- file1
$ getfacl file1
# file: file1
# owner: root
# group: root
user::rw-
user:tom:--x            #effective:---
group::r--                #effective:---
mask::---
other::r--

此时tom的有效权限是 ‘---’,因为mask权限掩盖了所有acl权限
但实际真这样么,其实这里有个小问题,tom用户对file1是有读权限的,因为mask禁用所有权限后,tom用户便重新属于了other,而other对file1是有读权限的

suid,sgid,sticky高级权限

现在来说一说前面的权限数字,0755、0664中的0是什么意思;这一位代表的便高级权限的数字,0表示没有高级权限,1代表sticky(粘滞位),2代表sgid,4代表suid

  • suid
    suid只能作用于可执行的二进制文件上,为什么?

suid的作用是使执行该二进制程序的人拥有二进制文件所有者的权限
所以suid只能作用于可执行的文件
看例子:

#### 当前为root账号
$ ll file2 
-rw-r----- 1 root root 0 Oct 12 01:37 /root/file2
#### 切换为tom账号
$ cat file2
cat: file2: Permission denied

#### 查看/etc/shadow文件,该文件用于存储用户密码
$ ll /etc/shadow
---------- 1 root root 685 Oct 12 01:42 /etc/shadow
#### 当前为tom用户,修改密码操作
$ passwd
#### ...
#### 最后发现在tom用户通过passwd密令更改了/etc/shadow文件

#### 为什么tom能通过passwd命令修改对于tom没有w权限/etc/shadow文件    
#### 而tom不能通过cat命令查看对于tom没有r权限的file2文件

$ ll /usr/bin/cat
-rwxr-xr-x. 1 root root 54080 Nov  6  2016 /usr/bin/cat
$ ll /usr/bin/passwd
-rwsr-xr-x. 1 root root 27832 Jun 10  2014 /usr/bin/passwd

通过例子可以看出,passwd命令与cat命令的区别在于passwd的权限是‘-rwsr-xr-x’,而cat命令的权限是‘-rwxr-xr-x’,这里passwd权限中原来所有者的x权限处变成了s,所以tom在通过passwd命令修改没有w权限的/etc/shadow时,会自动拥有/etc/shadow文件所有者root的权限(虽然文件对于root也没有w权限,但root用户有一切权限,即使文件对root没有权限也无所谓)

  • guid
    关于sgid,它有两个作用。一个是同suid类似,当sgid加在一个可执行的二进制文件时,使执行该文件的用户拥有它的所属组的所有权限;再一个就是,如果sgid加在一个目录上,则在该目录下创建的文件或目录的所属组和该目录一样,且创建的目录也会自动加上sgid
$ ll dir2 -d
drwx--s---  4 root tom  32 Oct 15 22:16 dir2
# dir2权限为2710,即0710又加了个sgid

# 此时umask为022,默认值
$ touch dir2/file1
$ ll dir2
-rw-r--r-- 1 root tom   0 Oct 15 22:20 file1
$ mkdir dir2/dir21
drwxr-sr-x 2 root tom   6 Oct 15 22:14 dir21
# dir21目录继承了dir2的sgid和所属组tom

$ umask 777
$ mkdir dir2/dir22
d-----S--- 2 root tom  17 Oct 15 22:16 dir22
# dir22目录继承了dir2的sgid,但由于dir22对于所属组没有x权限,
# 所以代表sgid的s变成了大写的,大写的S代表无效,
# 另外,suid加在对于所属主没有x权限的文件上也是大写的S
  • sticky
    我们知道,/tmp目录对于任何人都是可读可写可进入的,根据前面ugo权限可知,当一个目录对用户可写时,用户可以随意删除移动目录内的文件
$ ll /tmp/xxx.log
-rw-r--r-- 1 root root 122 Sep  9 16:02 /tmp/xxx.log
$ su - tom
$ rm -f /tmp/xxx.log
rm: cannot remove ‘/tmp/xxx.log’: Operation not permitted

为什么tom不能删除对于tom可写的/tmp目录下的xxx.log文件呢?

$ ll -d /tmp
drwxrwxrwt. 33 root root 8192 Oct 15 22:46 /tmp/

可以看到/tmp的权限多了个t,这便是sticky
sticky的目的是让用户只能删除移动自己的文件,对于不属于自己的文件,没权限删除或移动
对于sticky,目录必须对other有x权限,否则t变成大写,无效,why?
想想也容易理解,如果目录没有x权限,那么就不能进入目录,就更别提删除移动目录内的文件了,此时要sticky权限又有何用

说明:当使用chmod为文件或目录添加suid或sgid时,只能是‘chomd u+s/g+s file’,而不能是‘chmod o+s file’,o+s加也加不上;而给目录加sticky时,也只能是‘chmod o+t dir’;给目录加suid和给文件加sticky都能加上,但又有什么用呢?没啥用

SELinux

selinux是对标准linux权限的增强
所有操作系统访问控制都是以关联的客体主体的某种类型的访问控制属性为基础的。
怎么理解这句话?
操作系统:当然是linux等操作系统
访问控制:前面说的权限都可以说是访问控制
客体(object):主要是指文件、目录、端口等
主体(subject):主要是指进程
访问控制属性:对应标准linux权限的读写执行等权限,而对应selinux则叫做安全上下文(Security Context)
举例来说,主体进程httpd要访问一个客体网页文件a.html时,在没有selinux的情况下,需要看a.html的访问控制属性(即读取执行权限)是否对主体httpd进程开放
再看selinux的安全上下文是什么

# 查看文件的安全上下文
$ ll -Z /var/www/html 
-rw-r--r--. root root unconfined_u:object_r:admin_home_t:s0 a.html
-rw-r--r--. root root unconfined_u:object_r:httpd_sys_content_t:s0 index.html

# 查看进程的安全上下文
$ ps -ZC httpd
LABEL                              PID TTY          TIME CMD
system_u:system_r:httpd_t:s0      8083 ?        00:00:01 httpd
system_u:system_r:httpd_t:s0      8094 ?        00:00:00 httpd

# 查看端口安全上下文
$ semanage port -l | egrep '\<80\>'
http_port_t                    tcp      80, 81, 443, 488, 8008, 8009, 8443, 9000

这里主要说的是文件权限,对于进程和端口安全上下文先不做说明
在开启selinux的前提下,httpd服务器可以访问到index.html,而不能访问到a.html(会报403错误).为什么呢?原因就在于其安全上下文上
a.html的安全上下文:unconfined_u:object_r:admin_home_t:s0
index.html的安全上下文:unconfined_u:object_r:httpd_sys_content_t:s0
以分号分隔的几种安全上下文分别代表:USER:ROLE:TYPE[LEVEL[:CATEGORY]]
在默认安全策略targeted中,USER和ROLE对于文件几乎没什么影响,主要是TYPE,这里httpd不能访问a.html的原因也是由于两个文件的TYPE不同
selinux中有两种安全策略, targeted(常见的网络服务httpd、vsftpde受selinux控制)和strict(每个进程都受selinux的控制,这里主要说下targeteda,这也是默认的安全策略

  • 修改文件安全上下文
$ chcon -t httpd_sys_content_t /var/www/html/a.html
$ ll -Z /var/www/html/a.html
-rw-r--r--. root root unconfined_u:object_r:httpd_sys_content_t:s0 /var/www/html/a.html
  • selinux安全上下文规则
# 查看规则
$ semanage fcontext -l | grep "/var/www/html"
...
/var/www/html(/.*)?                                all files          system_u:object_r:httpd_sys_content_t:s0
...
# 添加规则(/var/www/html目录的所有php文件安全上下文标签为admin_home_t)
$ semanage fcontext -a -t admin_home_t "/var/www/html/(.*\.php)"
$ touch /var/www/html/1.php && ll -Z /var/www/html/1.php
-rw-r--r--. root root unconfined_u:object_r:httpd_sys_content_t:s0 /var/www/html/1.php
# 为什么新建的文件没有按照规则来生成admin_home_t标签的文件?因为文件生成是是根据父目录来的
# 如何让文件按照规则来改变安全上下文标签呢? 需要用到下面的命令:restorecon
# 重置规则
$ restorecon -RFv /var/www/html   # 将该目录按照该目录内的所有规则重置安全上下文标签
restorecon reset /var/www/html/1.php context unconfined_u:object_r:httpd_sys_content_t:s0->system_u:object_r:admin_home_t:s0

关于文件权限的selinux,就说到这里,selinux还包括除文件外的其它内容,如端口、进程等,以及其它细节方面的东西,我自己也还有好多不明白的,以后有时间弄明白了,单独另写一篇关于selinux的文章分享.本文是按照我边复习边写的,由于本人能力有限,文章可能有错或语句不通的地方,还请大家发现问题后及时提出,谢谢


化而为鸟
358 声望7 粉丝